home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / MM2_DEV / S / MOS / MOSCTRL.I < prev    next >
Encoding:
Text File  |  1994-06-24  |  21.3 KB  |  3 lines

  1. ⓪ IMPLEMENTATION MODULE MOSCtrl; (* V#0193 *)⓪ (*$Y+,N+,C+,L-,R-,M-*)⓪ ⓪ (*⓪"22.07.87: Bei Terminierung des gesamten MOS-Prozesses werden alle noch⓪,aktiven Modlevels abgebaut mit jew. Termprocess-Aufruf.⓪"30.08.87: ModLevel wird bei Push/PopPDB verändert. Bei unterstem ModLevel⓪,ist der Wert = 1.⓪"01.10.88: PopPDB wird bei Ende des untersten Prozesse aufgerufen, damit⓪,f. residente Prgs ModLevel dann auf Null steht.⓪"23.10.88: GetPDB liefert ggf. NIL (siehe Def-Text); Removal-Behandlung neu;⓪,Term-Handler wird bei residenten Programmen erst beim Freigeben⓪,ausgelinkt.⓪"15.01.89: PushPDB aktualisiert ggf. BaseProcess und ActMosProcess, da bei⓪.ACCs sonst Unsinn drin stünde.⓪"26.07.89: 408-Vektor wird auch bei residenten Prgs bei Prozeßende ausgelinkt.⓪"04.08.89: 408-Vektor wird mit XBRA ('MM2T') eingelinkt.⓪"16.08.89: Kein infinite Loop, wenn Runtime-Error bei Removal-Calls⓪"20.11.89: Process-ID wird bei TOS 1.0 wieder korrekt ermittelt - MM2 läuft⓪,nun wieder mit TOS 1.0⓪"21.11.90: Term-Handler: Wird bei ACCs nicht installiert, dafür aber nach⓪,Aushängung beim erneuten PushPDB (damit's mit ModLoad klappt);⓪,wenn während der Terminierung wieder Pterm aufgerufen wird, wird⓪,weitergemacht, als sei nix gewesen (die restlichen Term-Handler⓪,werden trotzdem aufgerufen usw).⓪,-nicht getestet!-⓪"25.11.90: Term-Handler: Wenn ein Modul mit TermProcess(0) zurückkehrt, wird⓪,der vorherige ExitCode/termState nicht verändert.⓪"08.12.90: Term-Handler: Der SSP wird nicht mehr aus Prozeß-Daten ermittelt⓪-(denn das Format könnte sich ja mal ändern), sondern wird auf⓪-den Startwert vom Prgstart zurückgesetzt.⓪"05.07.91: Term-Handler: ExitCode-Position wird gesucht, damit's auch mit⓪-KAOS klappt.⓪"03.02.92: 408-Vektor wird wg. MiNT per Bios-Funktion gesetzt.⓪"14.02.92: Wenn MiNT installiert, keine ExitCode-Positionssuche und Term-Hdlr⓪,läuft als Subroutine statt ein 2. Pterm am Ende zu machen.⓪"17.02.92: Wenn MiNT installiert, wird Term-Handler bei jedem neuen Prozeß⓪,in SetProcessState neu installiert. Achtung: bisher wird jedoch⓪,der alte Vektor vom Base-Prozeß jedesmal weiterhin gechained,⓪,obwohl MiNT eigentlich für den neuen Prozeß keine anderen Term-Hdlr⓪,mehr drin hat -> 'vSave' in der XBRA-Struktur müßte in PushPDB⓪,gestacked werden und jedesmal in SetProcessState neu gesetzt werden!⓪"19.02.92: Nun wird bei neuem Prozeß unabh. v. MiNT geprüft, ob der Term-Hdler⓪,noch in der etv_term-Kette installiert ist und ggf. neu installiert;⓪,Auf 408-Vektor wird wieder direkt statt über BIOS zugegriffen.⓪,Leider darf die Exitcode-Suche weiterhin nicht unter MiNT erfolgen,⓪,weil der nächste Supexec-Aufruf nach Pterm() zum Terminate führt.⓪"08.01.94: Mag!X-Anpassung (v. Dirk Steins): Ebenfalls keine Exitcode-Suche⓪"17.01.94: Neues Termination-Handling: 'PrgCtrl.TermProcess' führt bereits die⓪,Term-Handler vor Pterm() aus. Stellen wir im etv_term-Handler fest,⓪,daß noch nicht alles abgemeldet wurde, versuchen wir nicht mehr,⓪,den Exitcode zu korrigieren, denn das Abbrechen des Programms per⓪,Pterm() ist nicht mehr als "saubere" Methode erlaubt.⓪,Der etv_term-Handler wird am Ende immer per Pterm verlassen, auch⓪,bei MiNT/Magix.⓪"08.02.94: Korrektur seit 17.01.94: Falls wir, z.B. durch im Tochterprozeß⓪,noch installiertem GEMError, einen fremden Prozeß beenden, führen⓪,wir natürlich nicht die eigenen Term-Handler aus sondern rufen⓪,Pterm sofort auf.⓪"03.06.94: Noch ein Versuch wg. Problemen, falls ein Prg trotzdem GEMDOS-Pterm⓪,direkt aufruft und MetaDOS o.a. Prgs installiert sind, die im⓪,GEMDOS-Trap hängen und während des Pterm-Handlings mit aufgerufen⓪,werden und es nicht mögen, wenn dann der SSP auf dem fixen Pterm-⓪,Stack bereits steht: Vor Aufruf der Exit-Procs wird der SSP auf⓪,den Programm-USP gesetzt und der USP 512 Byte darunter. Am Ende,⓪,wenn die Exit-Procs ausgeführt wurden, wird wieder der alte SSP⓪,zurückgesetzt, damit es hoffentlich weiter mit rekursiven⓪,Pterms, wie bei Magix möglich, klappt.⓪"24.06.94: Falls ModCtrl BaseResident auf TRUE gesetzt hat und wir den⓪,Basisprozeß beenden, wird am Ende Ptermres statt Pterm aufgerufen.⓪ *)⓪ ⓪ FROM SYSTEM IMPORT ASSEMBLER, ADR, WORD, ADDRESS, TSIZE, LONGWORD, BYTE;⓪ ⓪ FROM MOSGlobals IMPORT MemArea;⓪ ⓪ (*⓪"FROM CookieJar IMPORT GetCookie;⓪ *)⓪ ⓪ (* ! Storage darf nicht importiert werden ! *)⓪ ⓪ ⓪ CONST layout = 4;⓪ ⓪&(*⓪'* Die folg. Konstante legt fest, wie viel Sicherheitsbereich der SSP⓪'* erhalten soll - gleich darunter wird der USP gelegt.⓪'*)⓪&SupervisorStackAmount = 512;⓪&⓪&(*⓪'* Ist die folg Konstanten TRUE, wird bei MiNT & Mag!X am Ende der⓪'* Prozeßterminierung im etv_term-Handler nicht erneut Pterm()⓪'* aufgerufen, sondern ein RTS ausgeführt. Das klappt auch, ist⓪'* aber z.Zt. offenbar überflüssig, da das Verfahren des wiederholten⓪'* Pterm-Aufrufs genausogut in allen Situationen zu klappen scheint.⓪'*)⓪&MiNTaware = FALSE;⓪ ⓪ VAR termVectorInstalled: BOOLEAN;⓪$TOSHdr: LONGWORD;⓪$(*$?MiNTaware:⓪&MagXavail, MiNTavail: BOOLEAN;⓪$*)⓪ ⓪ VAR PtermSSP, mySSP, myUSP: LONGCARD;⓪$didPterm: BYTE;⓪$makeResident: BYTE; (* wird gesetzt, falls InstallModule aufgerufen *)⓪8(* wurde, um dann Ptermres() aufzurufen         *)⓪ ⓪ VAR rem408carrier: RemovalEntry;⓪ ⓪ (*⓪ VAR LastSR : WORD;⓪ ⓪ PROCEDURE DisableIR;⓪"BEGIN⓪$ASSEMBLER⓪(PEA     upro(PC)⓪(MOVE    #38,-(A7)⓪(TRAP    #14⓪(ADDQ.L  #6,A7⓪(RTS⓪"upro  MOVE    SR,LastSR⓪(ORI     #$0700,SR⓪$END⓪"END DisableIR;⓪ ⓪ PROCEDURE EnableIR;⓪"BEGIN⓪$ASSEMBLER⓪(PEA     upro(PC)⓪(MOVE    #38,-(A7)⓪(TRAP    #14⓪(ADDQ.L  #6,A7⓪(RTS⓪"upro  MOVE    LastSR,SR⓪$END⓪"END EnableIR;⓪ *)⓪ ⓪ PROCEDURE GetPDB ( VAR pdbp : PtrPDB; VAR p: ADDRESS );⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.L  ProcessID,A1⓪(MOVE.L  (A1),D1           ; D1: akt. Prozeß⓪(MOVE.L  -(A3),A0⓪(MOVE.L  D1,(A0)⓪(MOVE.L  -(A3),A0⓪(TST     BaseIsAccessory   ; ist Programm ein ACC ?⓪(BEQ     notAcc⓪(CMPI    #1,ModLevel       ; und ist Acc-Prozeß aktiv?⓪(BEQ     mos               ; -> dann wird PDB geliefert⓪¬Acc⓪(CMP.L   ActMOSProcess,D1  ; Akt. Prozeß gleich letztem MOS-Prozeß ?⓪(BEQ     mos⓪(TST     ModLevel          ; oder kein MOS-Prozeß mehr aktiv ?⓪(BEQ     mos⓪(CLR.L   (A0)              ;  nein -> pdbp:= NIL⓪(RTS⓪&mos⓪(MOVE.L  ActPDB,(A0)⓪$END⓪"END GetPDB;⓪ ⓪ FORWARD HdlTerm;⓪ ⓪ PROCEDURE LookTermHdlr;⓪"BEGIN⓪$ASSEMBLER⓪(; Term-Handler suchen⓪(MOVE    SR,D2⓪(ORI     #$0700,SR⓪(LEA     HdlTerm,A2⓪(ADDA.W  #12,A2⓪(LEA     $408,A0         ; A0: Vektoradr.⓪%l: MOVE.L  (A0),A1⓪(CMPA.L  A2,A1           ; 'entry' gefunden?⓪(BEQ     f⓪(CMPI.L  #$58425241,-12(A1) ; Ist dies ein XBRA-Eintrag?⓪(BNE     n               ; Nein -> entry hier trotzdem austragen⓪(LEA     -4(A1),A0       ; Vorige Vektoradr. nach A0⓪(BRA     l⓪%n: MOVE.L  A2,A1⓪%f:⓪$END⓪"END LookTermHdlr;⓪ ⓪ PROCEDURE LinkOut408;⓪"BEGIN⓪$ASSEMBLER⓪(CLR.L   -(A7)⓪(MOVE    #$20,-(A7)      ; Super()⓪(TRAP    #1⓪(MOVE.L  D0,2(A7)⓪(⓪(; Term-Handler auslinken⓪(JSR     LookTermHdlr⓪(MOVE.L  -4(A1),(A0)     ; Entry.old eintragen⓪(CLR.W   termVectorInstalled⓪(MOVE    D2,SR⓪(⓪(TRAP    #1⓪(ADDQ.L  #6,A7⓪$END⓪"END LinkOut408;⓪ ⓪ PROCEDURE PushPDB ( pdb: PtrPDB; process: ADDRESS );⓪"BEGIN⓪$ASSEMBLER⓪(; JSR     DisableIR⓪(MOVE.L  -(A3),D1⓪(BLE.W   err⓪(MOVE.L  -(A3),D0⓪(BLE.W   err⓪(MOVE.L  D0,A0⓪(CMPI    #layout,PDB.layout(A0)⓪(BNE.W   err2⓪ ⓪(MOVE.L  D1,ActMOSProcess⓪(MOVE.L  PDB.basePageAddr(A0),A2⓪(LEA     ActPDB,A1⓪(MOVE.L  (A1),PDB.prev(A0)⓪(BNE     notBase⓪ ⓪(; *** unterster PDB wird init. ***⓪ ⓪(MOVE.L  A2,BaseProcess⓪(MOVE.L  A2,ActMOSProcess⓪(TST.L   $24(A2)⓪(SEQ     D0⓪(ANDI    #1,D0⓪(MOVE    D0,BaseIsAccessory⓪(MOVE.W  PDB.flags(A0),D0⓪(ANDI    #3,D0⓪(MOVE    D0,RealMode⓪ ⓪((*$?MiNTaware:⓪*MOVEM.L A0-A2,-(A7)⓪*⓪*; Ist MiNT installiert?⓪*MOVE.L  #$4D694E54,(A3)+⓪*SUBQ.L  #4,A7⓪*MOVE.L  A7,(A3)+⓪*JSR     GetCookie⓪*ADDQ.L  #4,A7           ; value ist uninteressant⓪*MOVE.W  -(A3),MiNTavail⓪"⓪*; Ist Mag!X installiert?⓪*MOVE.L  #$4D616758,(A3)+⓪*SUBQ.L  #4,A7⓪*MOVE.L  A7,(A3)+⓪*JSR     GetCookie⓪*ADDQ.L  #4,A7           ; value ist uninteressant⓪*MOVE.W  -(A3),MagXavail⓪"⓪*MOVEM.L (A7)+,A0-A2⓪(*)⓪ ⓪¬Base⓪(MOVE.L  A0,(A1)⓪(LEA     HdlTerm,A1      ; alten etv_term-Link retten, da er ggf. in⓪(MOVE.L  8(A1),PDB.prevTermHdlr(A0)   ; SetProcessState veränd. wird.⓪(MOVE.W  #2,PDB.termState(A0)⓪(CLR     ExitCode⓪(ADDQ.W  #1,ModLevel⓪ ⓪(; Da ACCs nie terminieren, braucht auch kein Term-Vektor installiert⓪(; werden. Ansonsten muß er immer so bald wie möglich installiert werden.⓪(; Dies ist der Fall beim 1. PushPDB-Aufruf in normalen Prgs und bei⓪(; einem Prozeß-Aufruf innerhalb von ACCs. Die Deinstallation muß auf⓪(; dem selben Level erfolgen. Macht sich z.B. ein Prg resident, muß⓪(; der Term-Vektor raus, aber wenn das res. Prg (z.B. ModLoad) dann⓪(; wieder einen Prozeß startet, muß der Term-Vektor wieder rein.⓪(TST.L   $24(A2)⓪(BEQ     noTermInstall   ; bei ACC-Prozeß keinen Term-Vektor installieren⓪(TST.W   termVectorInstalled⓪(BNE     noTermInstall   ; ansonsten installieren, wenn nicht schon getan⓪ ⓪(CLR.L   -(A7)⓪(MOVE    #$20,-(A7)      ; Super()⓪(TRAP    #1⓪(MOVE.L  D0,2(A7)⓪(⓪(; Pterm-Handler installieren⓪(LEA     HdlTerm,A1⓪(ADDA.W  #12,A1⓪(LEA     $408,A0         ; A0: Vektoradr.⓪(MOVE.L  (A0),-4(A1)     ; alten Vektor retten (in XBRA-Struktur)⓪(MOVE.L  A1,(A0)⓪(⓪(TRAP    #1              ; Super() - zurück in Usermode⓪(ADDQ.L  #6,A7⓪(⓪(; Catcher installieren, der beim Removal den etv_term wieder aushängt⓪(LEA     rem408carrier,A0⓪(MOVE.L  #LinkOut408,RemovalEntry.call(A0)⓪(MOVEQ   #0,D0⓪(MOVE.L  D0,RemovalEntry.wsp.bottom(A0)⓪(MOVE.L  D0,RemovalEntry.wsp.length(A0)⓪(LEA     RemovalRoot,A2               ; A2: root⓪(MOVE.L  A2,RemovalEntry.next(A0)⓪(MOVE.L  RemovalEntry.prev(A2),A1     ; A1: root.prev⓪(MOVE.L  A1,RemovalEntry.prev(A0)⓪(MOVE.L  A0,RemovalEntry.next(A1)⓪(MOVE.L  A0,RemovalEntry.prev(A2)⓪(⓪(MOVE    #1,termVectorInstalled⓪(⓪&noTermInstall:⓪(; JMP     EnableIR⓪(RTS⓪ ⓪&err2⓪(; JSR     EnableIR⓪(TRAP    #6⓪(DC.W    -16     ; internal fault⓪(RTS⓪&err⓪(; JSR     EnableIR⓪(TRAP    #6⓪(DC.W    -14     ; illegal call⓪$END⓪"END PushPDB;⓪ ⓪ PROCEDURE PopPDB;⓪"BEGIN⓪$ASSEMBLER⓪(; JSR     DisableIR⓪(LEA     ActPDB,A1⓪(MOVE.L  (A1),D0⓪(BEQ     err⓪(MOVE.L  D0,A0⓪(MOVE.L  PDB.prev(A0),(A1)⓪(LEA     HdlTerm,A1              ; alten etv_term-Link restaurieren⓪(MOVE.L  PDB.prevTermHdlr(A0),8(A1)⓪(MOVE.L  ProcessID,A0⓪(MOVE.L  (A0),ActMOSProcess⓪(SUBQ.W  #1,ModLevel⓪(BRA     ok⓪&err⓪(TRAP    #6⓪(DC.W    -14     ; illegal call⓪&ok⓪(; JSR     EnableIR⓪$END⓪"END PopPDB;⓪ ⓪ PROCEDURE SetProcessState ( state: CARDINAL );⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.W  -(A3),D1⓪(MOVE.L  ActPDB,D0⓪(BEQ     err⓪(MOVE.L  D0,A0⓪(MOVE.W  D1,PDB.processState(A0)⓪(CMPI    #1,D1⓪(BNE     notOne⓪(⓪(; neuer Prozeß gestartet⓪(;------------------------⓪(⓪(; zuerst in den Supervisormode⓪(CLR.L   -(A7)⓪(MOVE    #$20,-(A7)⓪(TRAP    #1⓪(MOVE.L  D0,2(A7)⓪(⓪(; SSP des Prozesses ermitteln⓪(MOVE.L  ActPDB,A0⓪(MOVE.L  D0,PDB.initialSSP(A0)⓪(⓪(; Term-Handler suchen⓪(JSR     LookTermHdlr    ; D2 enth. noch altes SR!⓪(⓪(; wenn TermHdlr noch installiert, ist alles OK⓪(BEQ     stillAvail⓪(⓪(; HdlTerm neu installieren⓪(MOVEA.W #$408,A0⓪(LEA     HdlTerm,A1⓪(ADDA.W  #12,A1⓪(MOVE.L  (A0),-4(A1)     ; alten Vektor retten (in XBRA-Struktur)⓪(MOVE.L  A1,(A0)⓪(⓪&stillAvail:⓪(MOVE    D2,SR           ; SR von LookTermHdlr zurücksetzen⓪(⓪(; zurück in der Usermode⓪(TRAP    #1⓪(ADDQ.L  #6,A7⓪(⓪¬One:⓪(RTS⓪(⓪&err:⓪(TRAP    #6⓪(DC.W    -14     ; illegal call⓪$END⓪"END SetProcessState;⓪ ⓪ ⓪ PROCEDURE CallSub ( subRoutine: PROC; VAR wsp: MemArea );⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.L  -(A3),A0                ; ^wsp⓪(MOVE.L  -(A3),A1                ; subRoutine⓪(⓪(MOVE.L  A3,-(A7)                ; A3 retten⓪(MOVE.L  A7,D1                   ; alten SP laden zum Retten⓪(⓪(MOVE.L  MemArea.bottom(A0),D0   ; neuen SP-Bottom⓪(BEQ     useOld                  ; alten SP verwenden⓪(MOVE.L  MemArea.length(A0),D2⓪(BEQ     useOld                  ; alten SP verwenden⓪(⓪(CMPI.L  #20,D2⓪(BCS     noStack                 ; Stack zu klein⓪(⓪(; neuen SP verwenden⓪(MOVE.L  D0,A3⓪(ADD.L   D2,D0⓪(MOVE.L  D0,A7⓪(⓪&useOld⓪(MOVE.L  D1,-(A7)                ; alten SP retten⓪(⓪(JSR     (A1)⓪(⓪(MOVE.L  (A7)+,A7⓪(MOVE.L  (A7)+,A3⓪(RTS⓪(⓪&noStack⓪(TRAP    #6⓪(DC.W    -10             ; out of stack space⓪$END⓪"END CallSub;⓪ ⓪ ⓪ PROCEDURE CallTermProcs;⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.L  ActPDB,D0⓪(BEQ     listEnd         ; Dürfte eigentlich nicht vorkommen⓪(MOVE.L  D0,A0⓪(LEA     PDB.termProcs(A0),A2⓪ lstLoop MOVE.L  (A2),D0⓪(BEQ     listEnd⓪(MOVE.L  D0,A0                     ; A0: POINTER TO ProcField⓪(MOVE.L  TermEntry.next(A0),(A2)   ; to be called next⓪(MOVE.L  TermEntry.call(A0),(A3)+  ; function to be called now⓪(LEA     TermEntry.wsp(A0),A1⓪(MOVE.L  A1,(A3)+⓪(MOVE.L  A2,-(A7)⓪(JSR     CallSub                   ; call term-function⓪(MOVE.L  (A7)+,A2⓪(BRA     lstLoop⓪ listEnd⓪$END⓪"END CallTermProcs;⓪ ⓪ ⓪ PROCEDURE CallRemoveProcs;⓪"(* alle Catcher in umgekehrter Anmeldereihenfolge aufrufen *)⓪"BEGIN⓪$ASSEMBLER⓪&l LEA     RemovalRoot,A2⓪(LEA     RemovalEntry.prev(A2),A2⓪(MOVE.L  (A2),A1⓪(CMPA.L  #RemovalRoot,A1⓪(BEQ     end2⓪(MOVE.L  RemovalEntry.prev(A1),(A2)      ; to be called next⓪(MOVE.L  RemovalEntry.call(A1),(A3)+⓪(LEA     RemovalEntry.wsp(A1),A0⓪(MOVE.L  A0,(A3)+⓪(JSR     CallSub⓪(BRA     l⓪&end2⓪$END⓪"END CallRemoveProcs;⓪ ⓪ ⓪ PROCEDURE callExitProcs;⓪"BEGIN⓪$ASSEMBLER⓪(JSR     CallTermProcs           ; Prozeßende mitteilen⓪(MOVE.L  ProcessID,A0⓪(MOVE.L  (A0),D0⓪(CMP.L   BaseProcess,D0          ; wird Basisprozeß beendet ?⓪(BNE     noBaseTerm⓪(TST.W   BaseResident            ; und ist Prg nicht resident ?⓪(BNE     noRemove⓪(JSR     CallRemoveProcs         ; -> Modul-Entfernung mitteilen⓪(BRA     doneRemove⓪ noRemove:⓪(ST      makeResident⓪ doneRemove:⓪(; Prg terminiert⓪(; **************⓪(CLR.L   BaseProcess⓪(CLR.L   ActMOSProcess⓪(CLR     ModLevel⓪ noBaseTerm:⓪$END⓪"END callExitProcs;⓪ ⓪ PROCEDURE setTermCode;⓪"BEGIN⓪$ASSEMBLER⓪(; Wenn ein Modul in der Deinit-Phase mit Exitcode 0 terminiert,⓪(; ist das kein Fehler.⓪(CMPI.W  #2,PDB.processState(A0) ; Init- oder Run-Phase?⓪(BLS     termNormal              ; ja, dann Exitcode auf jeden Fall nehmen⓪(TST     D1                      ; Deinit: Exitcode=0?⓪(BEQ     noError                 ; ja, dann alten Exitcode belassen⓪&termNormal:⓪(MOVE    D1,ExitCode⓪(MOVE.W  PDB.processState(A0),PDB.termState(A0)⓪&noError:⓪$END⓪"END setTermCode;⓪ ⓪ PROCEDURE terminateResident;⓪"BEGIN⓪$ASSEMBLER⓪(; ptermres (topOfStack-basepage, ExitCode)⓪(SF      makeResident⓪(MOVE.W  ExitCode,-(A7)⓪(MOVE.L  ActPDB,A0⓪(MOVE.L  PDB.topOfStack(A0),D0⓪(SUB.L   PDB.basePageAddr(A0),D0⓪(MOVE.L  D0,-(A7)⓪(MOVE    #$31,-(A7)⓪(TRAP    #1⓪(ADDQ.L  #8,A7⓪$END⓪"END terminateResident;⓪ ⓪ PROCEDURE HdlTerm;⓪"BEGIN⓪$ASSEMBLER⓪(ASC     'XBRA'  ; XBRA-Kennung⓪(ASC     'MM2T'  ; eigene Kennung⓪ save408 DC.L    0       ; old vector⓪ ⓪(; We're now in supervisor mode!⓪(MOVE.L  save408(PC),-(A7)⓪ ⓪(MOVE.L  ProcessID,A0⓪(MOVE.L  (A0),A1⓪(CMPA.L  BaseProcess,A1⓪(BEQ     term1⓪(CMPA.L  ActMOSProcess,A1⓪(BNE.W   notThis⓪ ⓪ term1   MOVE.L  ActPDB,D0⓪(BEQ.W   ende                    ; nanu?!⓪(MOVE.L  D0,A0⓪ ⓪(CMPI.W  #4,PDB.processState(A0)⓪(BCC.W   term2                   ; Prozeß ist bereits vollst. terminiert⓪ ⓪(; *** Prozeßterminierung nachholen ***⓪(⓪(MOVE    ExitCode,D1⓪(BNE     tellCode                ; falls kein ExitCode gesetzt,⓪(MOVEQ   #-1,D1                  ; -1 setzen (schließlich sollten wir⓪&tellCode:                         ; hier normalerweise nicht ankommen)⓪(JSR     setTermCode⓪(⓪(CMPI.W  #3,PDB.processState(A0)  ; bereits Deinit-Phase?⓪(BNE     firstPterm               ;   nein: Pterm-SSP merken⓪(TST.B   didPterm                 ; bereits Pterm-SSP ermittelt?⓪(BEQ     firstPterm               ;   nein: Pterm-SSP merken⓪(⓪((*⓪(idee: da am ende eh die bei rekursiven pterms benutzten stacks⓪(verworfen werden, kann gleich immer derselbe stack verwendet⓪(werden, so wie bei A3. allerdings muß ssp immer noch auf eigenen⓪(bereich zeigen (evtl. initialSSP?) und usp/ssp müssen⓪(geprüft werden, ob sie innerhalb des eigenen stacks bereits⓪(liegen und dann immer dieser wert verwendet werden, anstatt⓪(den stack neu auf dem vollbereich zu nutzen.⓪(*)⓪(⓪(MOVE.L  mySSP,A7        ; den bereits verwendeten SSP erneut benutzen⓪(BRA     noNewSSP⓪(⓪&firstPterm:⓪(MOVE.W  #3,PDB.processState(A0)  ; nun Deinit-Phase einleiten⓪(MOVE.L  A7,PtermSSP⓪(ST      didPterm⓪(⓪(; *** SSP & USP setzen ***⓪(; Dabei prüfen, ob der Pterm-SSP evtl. innerhalb unseres Prozeß-Stacks⓪(; liegt (z.B. verwendet MetaDOS bei Pterm den USP als SSP und ruft⓪(; dann selbst etv_term() auf). In diesem Fall wird der SSP weiterver-⓪(; wendet.⓪(CMPA.L  PDB.bottomOfStack(A0),A7⓪(BLS     notInside⓪(CMPA.L  PDB.topOfStack(A0),A7⓪(BLS     isInside⓪¬Inside:⓪(MOVE.L  PDB.topOfStack(A0),A7    ; new SSP: USP of terminated process⓪&isInside:⓪(MOVE.L  A7,mySSP⓪(⓪&noNewSSP:⓪(; *** setup Stack Pointers & enter User Mode ***⓪(MOVE.L  PDB.bottomOfStack(A0),A3 ; use stackptrs of terminated process⓪(MOVE.L  A7,A1⓪(SUBA.W  #SupervisorStackAmount,A1⓪(MOVE.L  A1,USP                  ; set USP to some bytes below SSP⓪(ANDI    #$DFFF,SR⓪(⓪(; *** call installed termination procedures ***⓪(; (last of them removes this handler from the etv_term vector)⓪(MOVE.L  A0,-(A7)                ; save PDB⓪(JSR     callExitProcs⓪(MOVE.L  (A7)+,A0                ; PDB zurück⓪(⓪(; *** process is terminated, all exit procs have been called ***⓪(MOVE.W  #4,PDB.processState(A0) ; process state: finished⓪(⓪(; *** call final 'Pterm' ***⓪(; (get into Superv Mode to restore SSP)⓪(CLR.L   -(A7)⓪(MOVE.W  #$20,-(A7)⓪(TRAP    #1                      ; enter Supervisor Mode to reset SSP⓪(MOVE.L  PtermSSP,A7             ; reset Pterm-SSP from first Pterm()⓪(TST.B   makeResident⓪(BNE     doTermRes⓪(; (no need to get back to User Mode)⓪(MOVE    ExitCode,-(A7)⓪(MOVE    #$4C,-(A7)⓪(TRAP    #1⓪(ADDQ.L  #6,A7⓪(BRA     ende⓪&doTermRes:⓪(JMP     terminateResident⓪ ⓪ term2:⓪ ende:⓪ notThis:⓪(; RTS-Wert ist geretteter $408-Vektor⓪$END⓪"END HdlTerm;⓪ ⓪ PROCEDURE Pterm (exitCode: INTEGER);⓪"BEGIN⓪$ASSEMBLER⓪(; Pterm-Behandlung von 'TermProcess' und M2Init aus.⓪(⓪(TST.L   ActPDB⓪(BEQ     term0                   ; nanu?!⓪(⓪(; ist es überhaupt unser eigener Prozeß, den wir hier beenden?⓪(MOVE.L  ProcessID,A1⓪(MOVE.L  (A1),A1⓪(CMPA.L  BaseProcess,A1⓪(BEQ     term1⓪(CMPA.L  ActMOSProcess,A1⓪(BEQ     term1⓪(⓪(; fremden Prozeß beenden -> Pterm() direkt aufrufen.⓪ term0:  MOVE    -(A3),-(A7)⓪(MOVE    #$4C,-(A7)⓪(TRAP    #1⓪ ⓪ term1:  ; eigenen Prozeß beenden -> vorher eigene Term-Handler aufrufen⓪ ⓪(; first get into User Mode⓪(MOVEQ   #1,D0⓪(MOVE.L  D0,-(A7)⓪(MOVE    #$20,-(A7)⓪(TRAP    #1              ; Super (1) - Get Mode⓪(ADDQ.L  #1,D0⓪(BNE     isUser⓪(ANDI    #$DFFF,SR       ; enter User Mode⓪&isUser:⓪(ADDQ.L  #6,A7⓪(⓪(MOVE    -(A3),D1        ; get exitCode⓪(MOVE.L  ActPDB,A0⓪ ⓪(JSR     setTermCode⓪(⓪(CMPI.W  #3,PDB.processState(A0)⓪(BEQ     notFirst⓪(MOVE.W  #3,PDB.processState(A0)  ; nun Deinit-Phase einleiten⓪(SF      didPterm⓪¬First:⓪ ⓪(; reload USP, do not change SSP here⓪(MOVE.L  PDB.bottomOfStack(A0),A3 ; use stackptrs of terminated process⓪(MOVE.L  PDB.topOfStack(A0),A7    ; new USP⓪(⓪(MOVE.L  A0,-(A7)                ; save PDB⓪(JSR     callExitProcs           ; may call this Pterm rekursively⓪(MOVE.L  (A7)+,A0                ; PDB zurück⓪(MOVE.W  #4,PDB.processState(A0)⓪(⓪(; call final 'Pterm'.⓪(TST.B   makeResident⓪(BNE     doTermRes⓪(; (no need to get back to User Mode)⓪(MOVE    ExitCode,-(A7)⓪(MOVE    #$4C,-(A7)⓪(TRAP    #1⓪(ADDQ.L  #6,A7⓪(BRA     ende⓪&doTermRes:⓪(JMP     terminateResident⓪&ende:⓪$END⓪"END Pterm;⓪ ⓪ BEGIN⓪"ASSEMBLER⓪(; supervisor mode:⓪(CLR.L   -(A7)⓪(MOVE    #$20,-(A7)⓪(TRAP    #1⓪(MOVE.L  D0,2(A7)⓪(MOVE.L  $4F2,A0         ; ^TOS-Header⓪(MOVE.L  8(A0),TOSHdr    ; wg. altem AHDI⓪(; back to user mode:⓪(TRAP    #1⓪(ADDQ.L  #6,A7⓪(⓪(MOVE.L  TOSHdr,A0⓪(CMPI    #$0102,2(A0)⓪(BCC     a⓪(MOVE    $1C(A0),D1⓪(LSR     #1,D1           ; PAL-Bit entfernen⓪(CMPI    #4,D1           ; Spanisches TOS?⓪(BEQ     b⓪(MOVE.L  #$602C, ProcessID⓪(BRA     e⓪%b: MOVE.L  #$873C, ProcessID⓪(BRA     e⓪%a: MOVE.L  $28(A0),ProcessID⓪%e:⓪(CLR     BaseIsAccessory⓪(CLR.L   BaseProcess⓪(CLR.W   BaseResident⓪(CLR.L   ActMOSProcess⓪(CLR.L   ActPDB⓪(CLR.W   ModLevel⓪(CLR.W   termVectorInstalled⓪(SF      makeResident⓪(LEA     EnvRoot,A0⓪(MOVE.L  A0,EnvEntry.prev(A0)⓪(MOVE.L  A0,EnvEntry.next(A0)⓪(LEA     RemovalRoot,A0⓪(MOVE.L  A0,RemovalEntry.next(A0)⓪(MOVE.L  A0,RemovalEntry.prev(A0)⓪"END⓪ END MOSCtrl.⓪ ə
  2. (* $FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$00001045$FFE3657B$000052D0$FFE3657B$00004857$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657B$FFE3657BÇ$00001042T.......T.......T.......T.......T.......T.......T.......T.......T.......T.......$00000D74$00001045$00000FBA$00001042$00001005$00001042$00004840$0000476E$FFDFF4EA$00004F18$00004EFC$00004F15$00004E43$000045BB$0000319C$000000F9ÿÇâ*)
  3.